from typing import NamedTuple

import contents
from ui import PlayerUi, PlayerMeUi


class player_type:
    assassin = {1: {"attack": 1, "skill_refactor": 1}, 2: {"skill": 1}, 3: {"attack": 1, "skill_refactor": 1},
                4: {"skill": 2}, 5: {"attack": 1, "skill_refactor": 1}}
    archer = {1: {"attack": 1, "max_hp": 1}, 2: {"skill": 1}, 3: {"attack": 1, "max_hp": 1},
              4: {"skill": 2}, 5: {"attack": 1, "max_hp": 1}}
    tank = {1: {"max_hp": 3}, 2: {"skill": 1}, 3: {"max_hp": 3},
            4: {"skill": 2}, 5: {"max_hp": 3}}


class PlayerInfo(NamedTuple):
    name: str
    id: str
    attack_range: int
    attack: int
    skill_refactor: int
    max_hp: int
    level: int
    coin: int
    type: dict[int:dict[str:int]]


player_map = {"巴莲之盾": PlayerInfo("巴莲之盾", "balianzhidun", 1, 1, 0, 20, 1, 0, player_type.tank),
              "斯诺"  : PlayerInfo("斯诺", "sino", 2, 1, 0, 18, 1, 0, player_type.archer),
              }


class BasePlayer:
    init_pos = 0

    def __init__(self, name, status, *args):
        super().__init__(*args)
        self.name, self.id, self.attack_range, self.attack, self.skill_refactor, self.max_hp, self.level, \
        self.coin, self.type = player_map[name]
        self.hp = self.max_hp
        self.status = status

        self.skills = []

        self.hand_cards = []
        self.set_hp()
        self.set_hand_card_num()
        self.enemy = None

        self.pos = self.init_pos
        self.avatar_card = None
        self.init_avatar()

        self.set_background()

    #################### avatar相关##########################################
    def init_avatar(self):
        event = self.create_event("init_avatar", 0)
        event.player = self
        event.index = self.pos
        event.num = 99999999
        event.prompt = self.id
        event.set_content(contents.add_avatar_card)

    ###################设置头像###############################################
    def set_background(self):
        super().set_background(self.id)

    ######### 创建event的方便函数###############################################
    def create_event(self, name, triggering=1):
        return self.status.event.create_event(name, triggering=triggering)

    #############skill相关####################################################
    def can_use_skill(self, skill):
        return True

    def use_skill(self, skill):
        if not self.can_use_skill(skill):
            return
        event = self.create_event("use_skill")
        event.player = self
        event.skill = skill
        event.set_content(contents.use_skill)

    ###############卡牌相关###################################################
    def add_hand_card(self, card):
        self.widget_items["hand_cards"].addWidget(card)
        card.setVisible(True)
        self.hand_cards.append(card)

    def remove_hand_card(self, card):
        self.widget_items["hand_cards"].removeWidget(card)
        card.setVisible(False)
        self.hand_cards.remove(card)

    def draw_cards(self, num, triggering=1):
        event = self.create_event("draw_cards", triggering)
        event.player = self
        event.num = num
        event.set_content(contents.draw_cards)

    def lose_hand_cards(self, cards):
        event = self.create_event("lose_hand_cards")
        event.player = self
        event.cards = cards
        event.set_content(contents.lose_hand_cards)

    def use_card(self, card):
        if isinstance(card, int):
            card = self.status.cards_index[card]

        event = self.create_event("use_card")
        event.player = self
        event.card = card
        event.set_content(contents.use_card)

    def find_card_by_skill(self, skill):
        return None

    ###############战场功能相关###################################################
    def choose_bool(self, confirm="确认", cancel="取消", prompt=""):
        event = self.create_event("choose_bool")
        event.player = self
        event.prompt = [confirm, cancel, prompt]
        event.set_content(contents.choose_bool)

    def move_to(self, pos):
        if pos > 6 or pos < 0:
            raise RuntimeError("移动到无效位置！")

        event = self.create_event("move_to")
        event.player = self
        event.pos = pos
        event.set_content(contents.move_to)

    def choose_field(self, fields=1, to_self=True):
        event = self.create_event("choose_field")
        event.player = self
        event.fields = fields
        event.to_self = to_self
        event.set_content(contents.choose_field)

    #################获得金币##########################################
    def change_coin(self, num):
        event = self.create_event("change_coin")
        event.player = self
        event.num = num
        event.set_content(contents.change_coin)

    #################使用金币##########################################
    def use_coin(self):
        event = self.create_event("use_coin")
        event.player = self
        event.set_content(contents.use_coin)

    ################升级###############################################
    def level_up(self):
        event = self.create_event("level_up")
        event.player = self
        event.set_content(contents.level_up)

    ##############改变最大生命值########################################
    def change_max_hp(self, delta):
        event = self.create_event("change_max_hp")
        event.player = self
        event.num = delta
        event.set_content(contents.change_max_hp)

    def add_skill(self, index):
        from skills import player_skills
        self.skills.extend(player_skills[self.id][index])
        super().add_skill(index)


class Player(BasePlayer, PlayerUi):
    init_pos = 1

    def __init__(self, *args):
        super(Player, self).__init__(*args)

    def is_me(self):
        return False


class PlayerMe(BasePlayer, PlayerMeUi):
    init_pos = 5

    def __init__(self, *args):
        super().__init__(*args)

    def is_me(self):
        return True

def create_player(name, is_me, status):
    if is_me:
        return PlayerMe(name, status)
    else:
        return Player(name, status)
